home *** CD-ROM | disk | FTP | other *** search
/ L' Effet Pommier 3 / L'Effet Pommier - Volume 03.iso / Programmation / gray image 2.1 / image_rect.cc < prev    next >
Text File  |  1995-05-03  |  4KB  |  144 lines

  1. // This may look like C code, but it is really -*- C++ -*-
  2. /*
  3.  ************************************************************************
  4.  *
  5.  *               Grayscale Image
  6.  *         Implementation of the Primitive Operations
  7.  *             on the rectangular area of the image
  8.  *
  9.  *   The image is represented as a Pixmap, i.e. a matrix of pixels
  10.  *    each of them specifies the gray level at a particular point
  11.  *
  12.  ************************************************************************
  13.  */
  14.  
  15. #include "image.h"
  16.  
  17. /*
  18.  *------------------------------------------------------------------------
  19.  *    Construct a new image from the rectangular area of another image
  20.  */
  21.  
  22. IMAGE::IMAGE(const Rectangle& ra)
  23. {
  24.   allocate(ra.nrows,ra.ncols,ra.image.bits_per_pixel);
  25.   register GRAY * ps = ra.ptr;
  26.   register GRAY * pi = pixels;
  27.   register int i,j;
  28.  
  29.   for(i=0; i < ra.nrows; i++, ps += ra.inc_to_nextrow)
  30.     for(j=0; j < ra.ncols; j++)        // Proceed scanline by scanline
  31.       *pi++ = *ps++;
  32.  
  33.   assert( pi == pixels + npixels );
  34. }
  35.  
  36. /*
  37.  *------------------------------------------------------------------------
  38.  *        Modify all the pixels in the rectangular area
  39.  *          according to a particular operation
  40.  */
  41.  
  42.                 // Perform "pixel OP val"
  43.  
  44. #define PIXEL_MODIFICATION_OP(OP)                    \
  45.                                     \
  46. Rectangle& Rectangle::operator OP (const int val)            \
  47. {                                    \
  48.   register GRAY * pp = ptr;                        \
  49.   register int i,j;                            \
  50.                                     \
  51.   for(i=0; i < nrows; i++, pp += inc_to_nextrow)            \
  52.     for(j=0; j < ncols; j++)        /*Proceed scanline by scanline*/\
  53.       *pp++ OP val;                            \
  54.                                     \
  55.   return *this;                                \
  56. }                                    \
  57.  
  58. PIXEL_MODIFICATION_OP(=)
  59. PIXEL_MODIFICATION_OP(+=)
  60. PIXEL_MODIFICATION_OP(-=)
  61. PIXEL_MODIFICATION_OP(*=)
  62. PIXEL_MODIFICATION_OP(|=)
  63. PIXEL_MODIFICATION_OP(&=)
  64. PIXEL_MODIFICATION_OP(^=)
  65.  
  66. #undef PIXEL_MODIFICATION_OP
  67.  
  68.                 // Shift the pixel values 
  69.                 // over the rectangular area to the left
  70. Rectangle& Rectangle::operator <<= (const int val)
  71. {
  72.   register GRAY_SIGNED * pp = (GRAY_SIGNED *)ptr;
  73.   register int i,j;
  74.  
  75.   if( abs(val) >= GRAY_MAXBIT )
  76.     _error("Very fishy shift factor: %d",val);
  77.  
  78.   for(i=0; i < nrows; i++, pp += inc_to_nextrow)
  79.     for(j=0; j < ncols; j++)        // Proceed scanline by scanline
  80.       *pp++ <<= val;
  81.  
  82.   return *this;
  83. }
  84.  
  85.                 // Shift the pixel values 
  86.                 // over the rectangular area to the right
  87. Rectangle& Rectangle::operator >>= (const int val)
  88. {
  89.   register GRAY_SIGNED * pp = (GRAY_SIGNED *)ptr;
  90.   register int i,j;
  91.  
  92.   if( abs(val) >= GRAY_MAXBIT )
  93.     _error("Very fishy shift factor: %d",val);
  94.  
  95.   for(i=0; i < nrows; i++, pp += inc_to_nextrow)
  96.     for(j=0; j < ncols; j++)        // Proceed scanline by scanline
  97.       *pp++ >>= val;
  98.  
  99.   return *this;
  100. }
  101.  
  102.  
  103.                     // Get a total sum of all the pixels
  104.                     // over the rectangular area
  105. double sum_over(const Rectangle& ra)
  106. {
  107.   register GRAY_SIGNED * pp = (GRAY_SIGNED *)ra.ptr;
  108.   register double sum = 0;
  109.   register int i,j;
  110.  
  111.   for(i=0; i < ra.nrows; i++, pp += ra.inc_to_nextrow)
  112.     for(j=0; j < ra.ncols; j++)        // Proceed scanline by scanline
  113.       sum += *pp++;
  114.  
  115.   return sum;
  116. }
  117.  
  118. /*
  119.  *------------------------------------------------------------------------
  120.  *        Operations on the rectangle area as a whole
  121.  */
  122.  
  123.                 // Copy a rectangle a_rect into the
  124.                 // rectangular area of the image
  125. Rectangle& Rectangle::operator = (const Rectangle& a_rect)
  126. {
  127.  
  128.   if( a_rect.nrows != nrows || a_rect.ncols != ncols )
  129.     _error("Rectangles %dx%d and %dx%d are incompatible",
  130.        a_rect.nrows,a_rect.ncols,nrows,ncols);
  131.  
  132.   register GRAY * sp = a_rect.ptr;        // Source and
  133.   register GRAY * dp = ptr;            // destination ptrs
  134.   register int i;
  135.  
  136.   for(i=0; i < nrows; i++)
  137.     memcpy(dp,sp,ncols*sizeof(GRAY)),
  138.     sp += a_rect.inc_to_nextrow + ncols, 
  139.     dp += inc_to_nextrow + ncols;
  140.  
  141.   return *this;
  142. }
  143.  
  144.